home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / CODECS.ZIP / codecs / francais / codrle4.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-13  |  8.2 KB  |  201 lines

  1. /* Fichier: codrle4.c
  2.    Auteur: David Bourgin
  3.    Date de creation: 1/2/94
  4.    Date de derniere mise a jour: 24/7/95
  5.    Dessein: Exemple de codage RLE type 4 avec comme donnees a compresser le contenu d'un fichier.
  6. */
  7.  
  8. #include <stdio.h>
  9. /* Pour les routines printf,fputc,fread et fwrite */
  10. #include <memory.h>
  11. /* Pour la routine memcpy */
  12. #include <stdlib.h>
  13. /* Pour la routine exit */
  14.  
  15. /* Codes d'erreur renvoyes a l'appelant */
  16. #define NO_ERROR      0
  17. #define BAD_FILE_NAME 1
  18. #define BAD_ARGUMENT  2
  19.  
  20. /* Constantes pratiques */
  21. #define FALSE 0
  22. #define TRUE  1
  23.  
  24. #define TAILLE_TRAME_MAX  65
  25.  
  26. /* Variables globales */
  27. FILE *f_source,*f_dest;
  28.  
  29. unsigned int index=0,
  30.              taille_tmp_lec=0;
  31. unsigned char tmp_lec[8224+2*65];
  32.  
  33. typedef struct { unsigned int taille_tab;
  34.                  unsigned char *val_tab;
  35.                } t_tab;
  36. #define TAILLE_TAB(tableau)  ((tableau).taille_tab)
  37. #define VAL_TAB(tableau)  ((tableau).val_tab)
  38. #define SONT_EGAUX(tableau1,tableau2)  ((TAILLE_TAB(tableau1)==TAILLE_TAB(tableau2))&&(!memcmp(VAL_TAB(tableau1),VAL_TAB(tableau2),TAILLE_TAB(tableau1))))
  39.  
  40. /* Pseudo procedures */
  41. #define charger_bloc()  { taille_tmp_lec=fread(tmp_lec,1,sizeof(tmp_lec),f_source); index=0; }
  42. #define repositionner_index(i)  (index=(i))
  43. #define taille_restante_a_lire()  (taille_tmp_lec-index)
  44. #define lire_tableau(tableau,nb_a_lire)  { TAILLE_TAB(tableau)=(nb_a_lire);\
  45.                                            VAL_TAB(tableau)= &(tmp_lec[index]);\
  46.                                            index += (nb_a_lire);\
  47.                                          }
  48. #define ecrire_octet(x)  ((void)fputc((unsigned char)(x),f_dest))
  49. #define ecrire_mot(x)  { ecrire_octet((x) >> 8); ecrire_octet((x) & 0xFF); }
  50. #define ecrire_tableau(tableau)  ((void)fwrite(VAL_TAB(tableau),1,TAILLE_TAB(tableau),f_dest))
  51. #define completer_bloc()  { (void)memcpy(tmp_lec,&(tmp_lec[index]),taille_restante_a_lire());\
  52.                             taille_tmp_lec=fread(&(tmp_lec[taille_restante_a_lire()]),1,sizeof(tmp_lec)-taille_restante_a_lire(),f_source)+taille_restante_a_lire();\
  53.                             index=0;\
  54.                           }
  55.  
  56. void chercher_occurrle4(index_basic,nb_trames,taille_trame,
  57.                         repetition_ok)
  58. /* Parametres en sortie: nb_trames, taille_trame et repetition_ok sont modifies
  59.    Action: Recherche dans le tampon d'octets a partir de la position index_basic une repetition de trame
  60.    dont la taille et la repetition seront respectivement dans taille_trame et nb_trames.
  61.    Si une repetition est rencontree, repetition_ok renvoie TRUE sinon repetition_ok renvoie FALSE
  62.    Erreurs: S'il n'y a pas de trames multiples alors nb_trames ne sera pas modifie
  63. */
  64. unsigned int index_basic,*nb_trames,*taille_trame;
  65. int *repetition_ok;
  66. { int egalite_des_tableaux;
  67.   t_tab tableau1,tableau2;
  68.  
  69.   *taille_trame=1;
  70.   *repetition_ok=FALSE;
  71.   repositionner_index(index_basic);
  72.   while ((*taille_trame<=TAILLE_TRAME_MAX)&&(taille_restante_a_lire()>=(*taille_trame << 1))&&(!*repetition_ok))
  73.         { lire_tableau(tableau1,*taille_trame);
  74.           lire_tableau(tableau2,*taille_trame);
  75.           if (egalite_des_tableaux=SONT_EGAUX(tableau1,tableau2))
  76.              { *nb_trames=2;
  77.                while ((taille_restante_a_lire()>=*taille_trame)
  78.                       &&(((*nb_trames<16449)&&(*taille_trame==1))||((*nb_trames<257)&&(*taille_trame>1)))
  79.                       &&(egalite_des_tableaux))
  80.                      { if ((*taille_trame>2)||(*nb_trames>2))
  81.                           { if (*repetition_ok)
  82.                                repositionner_index(*taille_trame);
  83.                             else { *repetition_ok=TRUE;
  84.                                    if (index_basic)
  85.                                       return;
  86.                                    repositionner_index((*nb_trames-1)*(*taille_trame));
  87.                                  }
  88.                             completer_bloc();
  89.                             repositionner_index(*taille_trame);
  90.                           }
  91.                        lire_tableau(tableau2,*taille_trame);
  92.                        if (egalite_des_tableaux=SONT_EGAUX(tableau1,tableau2))
  93.                           (*nb_trames)++;
  94.                      }
  95.                if ((*taille_trame>2)||(*nb_trames>2))
  96.                   { if (index_basic)
  97.                        { *repetition_ok=TRUE;
  98.                          return;
  99.                        }
  100.                     if (*repetition_ok)
  101.                        { if (egalite_des_tableaux)
  102.                             { repositionner_index(*taille_trame);
  103.                               completer_bloc();
  104.                             }
  105.                        }
  106.                     else { *repetition_ok=TRUE;
  107.                            repositionner_index((*nb_trames-1)*(*taille_trame));
  108.                            completer_bloc();
  109.                          }
  110.                     (*taille_trame)--;
  111.                   }
  112.                              /* Specifier a l'appelant qu'il y a eu repetition */
  113.              }
  114.           (*taille_trame)++;
  115.           repositionner_index(index_basic);
  116.         }
  117. }
  118.  
  119. void codagerle4()
  120. /* Parametres en sortie: Aucun
  121.    Action: Compresse suivant la methode RLE type 4 tous les octets lus par la fonction lire_octet
  122.    Erreurs: Une erreur d'entree/sortie peut perturber le deroulement de l'algorithme
  123. */
  124. { t_tab trame;
  125.   unsigned int nb_trames1,taille_trame1,nb_trames2,taille_trame2;
  126.   int repetition_valide;
  127.  
  128.   charger_bloc();
  129.   while (taille_restante_a_lire())
  130.         { chercher_occurrle4(0,&nb_trames1,&taille_trame1,&repetition_valide);
  131.           if (repetition_valide)
  132.                              /* Il y a eu repetition? */
  133.              { if (taille_trame1==1)
  134.                              /* Trame a 1 octet? */
  135.                   { if (nb_trames1<66)
  136.                              /* Trame a 1 octet mais moins de 66 fois? */
  137.                        ecrire_octet(nb_trames1-2);
  138.                     else ecrire_mot(nb_trames1+16318);
  139.                   }
  140.                else {        /* Trame a plusieurs octets */
  141.                       ecrire_octet(taille_trame1+126);
  142.                       ecrire_octet(nb_trames1-2);
  143.                     }
  144.              }
  145.           else { taille_trame1=0;
  146.                  do {        /* Teste jusqu'ou il n'y a pas repetition */
  147.                       taille_trame1++;
  148.                       chercher_occurrle4(taille_trame1,&nb_trames2,&taille_trame2,&repetition_valide);
  149.                     }
  150.                  while ((taille_restante_a_lire())&&(taille_trame1<8224)&&(!repetition_valide));
  151.                  if (taille_trame1<33)
  152.                              /* Non repetition de trame avec moins de 33 octets */
  153.                     ecrire_octet(taille_trame1+191);
  154.                  else ecrire_mot(taille_trame1+57311);
  155.                }
  156.           repositionner_index(0);
  157.           lire_tableau(trame,taille_trame1);
  158.           ecrire_tableau(trame);
  159.           completer_bloc();  /* Toute nouvelle analyse doit debuter dans le tampon en 0 */
  160.         }
  161. }
  162.  
  163. void aide()
  164. /* Parametres en sortie: Aucun
  165.    Action: Affiche l'aide du programme et termine son execution
  166.    Erreurs: Aucune
  167. */
  168. { printf("Cet utilitaire permet de compresser un fichier par la methode RLE type 4\n");
  169.   printf("telle qu'elle est exposee dans 'La Video et Les Imprimantes sur PC'\n");
  170.   printf("\nUsage: codrle4 source destination\n");
  171.   printf("source: Nom du fichier a compresser\n");
  172.   printf("destination: Nom du fichier compresse\n");
  173. }
  174.  
  175. int main(argc,argv)
  176. /* Parametres en sortie: Renvoie un code d'erreur (0=Aucune)
  177.    Action: Procedure principale
  178.    Erreurs: Detectee, traitee et un code d'erreur est renvoye si necessaire
  179. */
  180. int argc;
  181. char *argv[];
  182. { if (argc!=3)
  183.      { aide();
  184.        exit(BAD_ARGUMENT);
  185.      }
  186.   else if ((f_source=fopen(argv[1],"rb"))==NULL)
  187.           { aide();
  188.             exit(BAD_FILE_NAME);
  189.           }
  190.        else if ((f_dest=fopen(argv[2],"wb"))==NULL)
  191.                { aide();
  192.                  exit(BAD_FILE_NAME);
  193.                }
  194.             else { codagerle4();
  195.                    fclose(f_source);
  196.                    fclose(f_dest);
  197.                  }
  198.   printf("Execution de codrle4 achevee.\n");
  199.   return (NO_ERROR);
  200. }
  201.